#include <read.h>

bool bigEndian;

//! Reads an 8 bit signed integer from the serial port.
std::string readInt8(serialib &serial)
{
    int8_t data;
    serial.readBytes(&data, 1, 0, 0);
    return std::to_string(data);
}

//! Reads an 16 bit signed integer from the serial port.
std::string readInt16(serialib &serial)
{
    uint8_t h;
    uint8_t l;
    
    if (bigEndian)
    {
        serial.readBytes(&h, 1, 0, 0);
        serial.readBytes(&l, 1, 0, 0);
    }
    else
    {
        serial.readBytes(&l, 1, 0, 0);
        serial.readBytes(&h, 1, 0, 0);
    }
    
    int16_t data = (h << 8 ) | (l & 0xff);
    return std::to_string(data);
}

//! Reads an 32 bit signed integer from the serial port.
std::string readInt32(serialib &serial)
{
    uint8_t bytes [4];
    
    if (bigEndian)
    {
        for (int i = 0; i < 4; ++i)
        {
            serial.readBytes(&bytes[i], 1, 0, 0);
        }
    }
    else
    {
        for (int i = 3; i >= 0; i--)
        {
            serial.readBytes(&bytes[i], 1, 0, 0);
        }
    }
    
    int32_t data = (bytes[0] << 24) | (bytes[1] << 16) | ( bytes[2] << 8 ) | (bytes[3]);
    return std::to_string(data);
}

//! Reads an 8 bit unsigned integer from the serial port.
std::string readUint8(serialib &serial)
{
    uint8_t data;
    serial.readBytes(&data, sizeof(uint8_t), 0, 0);
    return std::to_string(data);
}

//! Reads an 16 bit unsigned integer from the serial port.
std::string readUint16(serialib &serial)
{
    uint8_t h;
    uint8_t l;
    
    if (bigEndian)
    {
        serial.readBytes(&h, 1, 0, 0);
        serial.readBytes(&l, 1, 0, 0);
    }
    else
    {
        serial.readBytes(&l, 1, 0, 0);
        serial.readBytes(&h, 1, 0, 0);
    }
    
    uint16_t data = (h << 8 ) | (l & 0xff);
    return std::to_string(data);
}

//! Reads an 32 bit unsigned integer from the serial port.
std::string readUint32(serialib &serial)
{
    uint8_t bytes [4];
    
    if (bigEndian)
    {
        for (int i = 0; i < 4; ++i)
        {
            serial.readBytes(&bytes[i], 1, 0, 0);
        }
    }
    else
    {
        for (int i = 3; i >= 0; i--)
        {
            serial.readBytes(&bytes[i], 1, 0, 0);
        }
    }
    
    uint32_t data = (bytes[0] << 24) | (bytes[1] << 16) | ( bytes[2] << 8 ) | (bytes[3]);
    return std::to_string(data);
}

//! Reads an 32 bit float from the serial port.
std::string readFloat(serialib &serial)
{
    uint8_t bytes [4];
    
    if (bigEndian)
    {
        for (int i = 0; i < 4; ++i)
        {
            serial.readBytes(&bytes[i], 1, 0, 0);
        }
    }
    else
    {
        for (int i = 3; i >= 0; i--)
        {
            serial.readBytes(&bytes[i], 1, 0, 0);
        }
    }
    
    long data = (bytes[0] << 24) | (bytes[1] << 16) | ( bytes[2] << 8 ) | (bytes[3]);
    union
    {
      long l;
      float f;
    }uData;
    uData.l = data;
    return std::to_string(uData.f);
}

//! Reads an 32 bit double from the serial port.
std::string readDouble(serialib &serial)
{
    uint8_t bytes [4];
    
    if (bigEndian)
    {
        for (int i = 0; i < 4; ++i)
        {
            serial.readBytes(&bytes[i], 1, 0, 0);
        }
    }
    else
    {
        for (int i = 3; i >= 0; i--)
        {
            serial.readBytes(&bytes[i], 1, 0, 0);
        }
    }
    
    long data = (bytes[0] << 24) | (bytes[1] << 16) | ( bytes[2] << 8 ) | (bytes[3]);
    union
    {
      long l;
      double d;
    }uData;
    uData.l = data;
    return std::to_string(uData.d);
}